package com.sleepsocial.api.authentication;

import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.google.appengine.api.datastore.KeyFactory;
import com.sleepsocial.api.Api;
import com.sleepsocial.api.beans.ApiAuthenticationResponse;
import com.sleepsocial.api.error.ApiError;
import com.sleepsocial.authentication.AuthenticationException;
import com.sleepsocial.authentication.AuthenticationManager;
import com.sleepsocial.authentication.SignupException;
import com.sleepsocial.logging.Logger;
import com.sleepsocial.persistency.entity.user.UserProfile;
import com.sleepsocial.security.PasswordGenerator;

@Controller
@RequestMapping(value = Api.API_BASE_URL + "/auth")
public class ApiAuthenticationController extends Api {

    private static final Logger LOG = Logger.getInstance(ApiAuthenticationController.class.getSimpleName());

    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public @ResponseBody
    ApiAuthenticationResponse authenticate(@RequestParam String email, @RequestParam String password, HttpServletResponse res) {
        return authenticate(email, AuthenticationManager.generatePasswordHash(password), res);
    }

    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public @ResponseBody
    ApiAuthenticationResponse authenticateWithHash(@RequestParam String email, @RequestParam String hash, HttpServletResponse res) {
        UserProfile profile = null;
        ApiAuthenticationResponse response = new ApiAuthenticationResponse();
        try {
            profile = AuthenticationManager.authenticate(email, hash, res);
        } catch (AuthenticationException e) {
            LOG.i("Unable to authenticate user", e);
            response.setError(new ApiError(e));
        }

        if (profile != null) {
            response.setAuthenticated(true);
            response.setProfile(profile);
            response.setUserKey(KeyFactory.keyToString(profile.getKey()));
        } else {
            response.setError(new ApiError("Email or password does not match. Please check the entered information"));
        }
        return response;
    }

    @RequestMapping(value = "/signup", method = RequestMethod.POST)
    public ApiAuthenticationResponse signup(@RequestParam String email, @RequestParam(required = false) String password, HttpServletResponse res) {
        ApiAuthenticationResponse response = new ApiAuthenticationResponse();
        UserProfile profile = null;
        if (password == null) {
            LOG.i("Generating a password for user[" + email + "]");
            password = PasswordGenerator.generate();
        }
        try {
            profile = AuthenticationManager.signup(email, password);
            profile = AuthenticationManager.authenticate(email, password, res);
        } catch (SignupException e) {
            LOG.i("Unable to signup user", e);
            response.setError(new ApiError(e));
        } catch (AuthenticationException e) {
            response.setError(new ApiError(e));
            LOG.i("Unable to authenticate user", e);
        }

        response.setAuthenticated(profile == null ? false : true);
        if (profile != null) {
            response.setProfile(profile);
            response.setUserKey(KeyFactory.keyToString(profile.getKey()));
        }

        return response;
    }
}
